Skip to content

feat: mergeStateStatus in delta summary + opt-in baseline-state emission - #20

Merged
diegomarino merged 5 commits into
mainfrom
feat/merge-state-status-and-baseline-emit
Jul 28, 2026
Merged

feat: mergeStateStatus in delta summary + opt-in baseline-state emission#20
diegomarino merged 5 commits into
mainfrom
feat/merge-state-status-and-baseline-emit

Conversation

@diegomarino

Copy link
Copy Markdown
Owner

Two additive contract features requested by the downstream consumer gh-delta-orca. Both are additive under report.schemaVersion === 1 (no bump), fail-closed, and independently shippable.

Feature 1 — mergeStateStatus in the delta summary

summary.mergeable only distinguishes mergeable | conflicting | unknown, so a PR that is approved, CI-green and mergeable but which GitHub still refuses to merge — because the branch is behind the base (repos that require branches be up to date) or blocked by an unsatisfied protection rule — was indistinguishable from a genuinely ready PR. Consumers emitted a false "ready to merge".

  • New summary.mergeStateStatus (PR deltas under --summaries), sourced from GitHub's mergeStateStatus in the same single observation that builds the fingerprint (no extra fetch).
  • Closed, lowercased, fail-closed enum: behind | blocked | clean | dirty | draft | has_hooks | unstable | unknown. Null/absent/unrecognized → unknown ("not computed", exactly like mergeable: unknown).
  • Stored raw in the PR fingerprint but stripped from change comparison and the delta id (like ciChecks / reviewSummary), so it never fires a spurious delta and older snapshots that gain the key diff to zero.
  • Exported through both machine-readable surfaces (DELTA_SUMMARY_FIELDS / DELTA_SUMMARY_ENUMS, --help-json output.deltaSummaryFields / output.deltaSummaryEnums), the contract summary + fingerprint tables, and the README.

Feature 2 — opt-in baseline state emission (--baseline-emit-state)

The first run seeds a baseline with deltas: [], so state that already exists at baseline (a PR already conflicting, already CI-blocked) never produces a delta until the PR changes again — a stuck PR could stay invisible forever.

  • New opt-in boolean flag, off by default (existing behavior byte-identical).
  • When on and the run seeds a baseline: emits one synthetic delta per tracked OPEN item (PRs and issues within --entities) with a new closed-set class baseline-statefrom: null, to the freshly observed fingerprint, summary present for PR deltas under --summaries.
  • Delta id is content-addressed under the existing scheme (which excludes classes when to != null), so re-baselining over unchanged state yields identical ids — idempotent consumers dedupe for free.
  • When ≥1 baseline-state delta is emitted the run exits 10 with baseline: true and a non-empty deltas array. Contract's "when baseline is true, deltas is always []" sentence scoped to runs without the flag; exit-code section notes watchers chaining on exit 10 feed the baseline report like any other.
  • Consumers must not treat baseline-state as newly created (mirrors first-seen).

Consumer fit (gh-delta-orca)

Maps mergeStateStatus: behindbehind_base blockage; requires clean | unstable | has_hooks (or field absent) for its ready signal; feeds baseline-state deltas through its normal pipeline unchanged (it already tolerates unknown classes).

Tests & verification

  • 259 tests pass; npm run check (lint + format:check + test) is clean.
  • New coverage: GraphQL query requests mergeStateStatus + boundary default; fingerprint stores-but-strips it (no phantom delta on upgrade); every mergeStateStatus enum value normalizes; --help-json advertises the field/enum/flag; --summaries surfaces behind; baseline-state off/on, id-stability across re-baseline, and --summaries interaction; the frozen contract-class guardrail forced the text-output suggested-action entry.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b903d4ba5f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/fingerprint.mjs Outdated
…lowed

A CLEAN->BEHIND transition (base branch advances, nothing else changes) was
dropped because mergeStateStatus was excluded from the fingerprint comparison,
silently writing the new status to the snapshot and leaving consumers at a stale
'ready to merge'. Treat it as a compared field like mergeable: transitions fire an
updated delta and enter the delta id. A snapshot predating the field is suppressed
pairwise so the first post-upgrade tick does not emit a fleet-wide spurious burst.
@diegomarino
diegomarino merged commit 7502787 into main Jul 28, 2026
3 checks passed
@diegomarino
diegomarino deleted the feat/merge-state-status-and-baseline-emit branch July 28, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant